package handler

import (
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/slrun/callcenter/internal/model"
	"github.com/slrun/callcenter/internal/service"
)

// TicketHandler 工单处理器
type TicketHandler struct {
	Services *service.Services
}

// NewTicketHandler 创建工单处理器
func NewTicketHandler(services *service.Services) *TicketHandler {
	return &TicketHandler{Services: services}
}

// CreateTicket 创建工单
func (h *TicketHandler) CreateTicket(c *gin.Context) {
	var req model.TicketCreateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	// 获取当前用户信息
	userID := getUserIDFromContext(c)
	userName := getUserNameFromContext(c)

	// 创建工单
	ticket, err := h.Services.TicketService.CreateTicket(req, userID, userName)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建工单失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusCreated, ticket)
}

// GetTicket 获取工单详情
func (h *TicketHandler) GetTicket(c *gin.Context) {
	ticketID := c.Param("id")
	if ticketID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "工单ID不能为空"})
		return
	}

	ticket, err := h.Services.TicketService.GetTicket(ticketID)
	if err != nil {
		if err.Error() == "工单不存在" {
			c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "获取工单失败: " + err.Error()})
		}
		return
	}

	c.JSON(http.StatusOK, ticket)
}

// UpdateTicket 更新工单
func (h *TicketHandler) UpdateTicket(c *gin.Context) {
	ticketID := c.Param("id")
	if ticketID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "工单ID不能为空"})
		return
	}

	var req model.TicketUpdateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	// 获取当前用户信息
	userID := getUserIDFromContext(c)
	userName := getUserNameFromContext(c)

	// 更新工单
	ticket, err := h.Services.TicketService.UpdateTicket(ticketID, req, userID, userName)
	if err != nil {
		if err.Error() == "工单不存在" {
			c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "更新工单失败: " + err.Error()})
		}
		return
	}

	c.JSON(http.StatusOK, ticket)
}

// AssignTicket 分配工单
func (h *TicketHandler) AssignTicket(c *gin.Context) {
	ticketID := c.Param("id")
	if ticketID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "工单ID不能为空"})
		return
	}

	var req model.TicketAssignRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	// 获取当前用户信息
	userID := getUserIDFromContext(c)
	userName := getUserNameFromContext(c)

	// 分配工单
	ticket, err := h.Services.TicketService.AssignTicket(ticketID, req, userID, userName)
	if err != nil {
		if err.Error() == "工单不存在" {
			c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "分配工单失败: " + err.Error()})
		}
		return
	}

	c.JSON(http.StatusOK, ticket)
}

// SearchTickets 搜索工单
func (h *TicketHandler) SearchTickets(c *gin.Context) {
	var criteria model.TicketSearchCriteria

	// 绑定查询参数
	if err := c.ShouldBindQuery(&criteria); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "查询参数错误: " + err.Error()})
		return
	}

	// 解析分页参数
	page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
	if err != nil || page < 1 {
		page = 1
	}
	criteria.Page = page

	pageSize, err := strconv.Atoi(c.DefaultQuery("page_size", "20"))
	if err != nil || pageSize < 1 || pageSize > 100 {
		pageSize = 20
	}
	criteria.PageSize = pageSize

	// 解析日期参数
	if startDateStr := c.Query("start_date"); startDateStr != "" {
		startDate, parseErr := time.Parse(time.RFC3339, startDateStr)
		if parseErr == nil {
			criteria.StartDate = startDate
		}
	}

	if endDateStr := c.Query("end_date"); endDateStr != "" {
		endDate, parseErr := time.Parse(time.RFC3339, endDateStr)
		if parseErr == nil {
			criteria.EndDate = endDate
		}
	}

	if dueDateFromStr := c.Query("due_date_from"); dueDateFromStr != "" {
		dueDateFrom, parseErr := time.Parse(time.RFC3339, dueDateFromStr)
		if parseErr == nil {
			criteria.DueDateFrom = dueDateFrom
		}
	}

	if dueDateToStr := c.Query("due_date_to"); dueDateToStr != "" {
		dueDateTo, parseErr := time.Parse(time.RFC3339, dueDateToStr)
		if parseErr == nil {
			criteria.DueDateTo = dueDateTo
		}
	}

	// 设置排序参数
	criteria.SortBy = c.DefaultQuery("sort_by", "created_at")
	criteria.SortOrder = c.DefaultQuery("sort_order", "desc")

	// 搜索工单
	tickets, total, err := h.Services.TicketService.SearchTickets(criteria)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "搜索工单失败: " + err.Error()})
		return
	}

	// 计算总页数
	totalPages := int(total) / pageSize
	if int(total)%pageSize > 0 {
		totalPages++
	}

	c.JSON(http.StatusOK, gin.H{
		"data":        tickets,
		"total":       total,
		"page":        page,
		"page_size":   pageSize,
		"total_pages": totalPages,
	})
}

// AddComment 添加工单评论
func (h *TicketHandler) AddComment(c *gin.Context) {
	ticketID := c.Param("id")
	if ticketID == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "工单ID不能为空"})
		return
	}

	var req model.TicketCommentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	// 获取当前用户信息
	userID := getUserIDFromContext(c)
	userName := getUserNameFromContext(c)

	// 添加评论
	ticket, err := h.Services.TicketService.AddComment(ticketID, req, userID, userName)
	if err != nil {
		if err.Error() == "工单不存在" {
			c.JSON(http.StatusNotFound, gin.H{"error": err.Error()})
		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "添加评论失败: " + err.Error()})
		}
		return
	}

	c.JSON(http.StatusOK, ticket)
}

// GetTicketStatistics 获取工单统计
func (h *TicketHandler) GetTicketStatistics(c *gin.Context) {
	stats, err := h.Services.TicketService.GetTicketStatistics()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取工单统计失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, stats)
}

// BatchUpdateTickets 批量更新工单
func (h *TicketHandler) BatchUpdateTickets(c *gin.Context) {
	var req struct {
		TicketIDs []string                  `json:"ticket_ids" binding:"required"`
		Updates   model.TicketUpdateRequest `json:"updates"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	if len(req.TicketIDs) == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请选择要更新的工单"})
		return
	}

	if len(req.TicketIDs) > 100 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "一次最多更新100个工单"})
		return
	}

	// 获取当前用户信息
	userID := getUserIDFromContext(c)
	userName := getUserNameFromContext(c)

	// 批量更新
	var updatedTickets []*model.Ticket
	var failedTickets []string

	for _, ticketID := range req.TicketIDs {
		ticket, err := h.Services.TicketService.UpdateTicket(ticketID, req.Updates, userID, userName)
		if err != nil {
			failedTickets = append(failedTickets, ticketID)
		} else {
			updatedTickets = append(updatedTickets, ticket)
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"updated":      updatedTickets,
		"failed":       failedTickets,
		"total":        len(req.TicketIDs),
		"success":      len(updatedTickets),
		"failed_count": len(failedTickets),
	})
}

// BatchAssignTickets 批量分配工单
func (h *TicketHandler) BatchAssignTickets(c *gin.Context) {
	var req struct {
		TicketIDs  []string                  `json:"ticket_ids" binding:"required"`
		Assignment model.TicketAssignRequest `json:"assignment" binding:"required"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	if len(req.TicketIDs) == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "请选择要分配的工单"})
		return
	}

	if len(req.TicketIDs) > 100 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "一次最多分配100个工单"})
		return
	}

	// 获取当前用户信息
	userID := getUserIDFromContext(c)
	userName := getUserNameFromContext(c)

	// 批量分配
	var assignedTickets []*model.Ticket
	var failedTickets []string

	for _, ticketID := range req.TicketIDs {
		ticket, err := h.Services.TicketService.AssignTicket(ticketID, req.Assignment, userID, userName)
		if err != nil {
			failedTickets = append(failedTickets, ticketID)
		} else {
			assignedTickets = append(assignedTickets, ticket)
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"assigned":     assignedTickets,
		"failed":       failedTickets,
		"total":        len(req.TicketIDs),
		"success":      len(assignedTickets),
		"failed_count": len(failedTickets),
	})
}

// QuickCreateTicket 快速创建工单
func (h *TicketHandler) QuickCreateTicket(c *gin.Context) {
	var req struct {
		CustomerPhone string               `json:"customer_phone" binding:"required"`
		Title         string               `json:"title" binding:"required"`
		Description   string               `json:"description"`
		Type          model.TicketType     `json:"type"`
		Priority      model.TicketPriority `json:"priority"`
		RelatedCallID string               `json:"related_call_id"`
	}

	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: " + err.Error()})
		return
	}

	// 获取当前用户信息
	userID := getUserIDFromContext(c)
	userName := getUserNameFromContext(c)

	// 构建工单创建请求
	ticketReq := model.TicketCreateRequest{
		Title:         req.Title,
		Description:   req.Description,
		Type:          req.Type,
		Source:        model.TicketSourcePhone,
		Priority:      req.Priority,
		CustomerPhone: req.CustomerPhone,
		CustomerName:  req.CustomerPhone, // 快速创建时使用电话作为名称
		RelatedCallID: req.RelatedCallID,
	}

	// 创建工单
	ticket, err := h.Services.TicketService.CreateTicket(ticketReq, userID, userName)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "快速创建工单失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusCreated, ticket)
}

// 从上下文获取用户ID的辅助函数
func getUserIDFromContext(c *gin.Context) string {
	// 这里假设用户信息已经通过JWT中间件注入到上下文中
	if userID, exists := c.Get("user_id"); exists {
		if id, ok := userID.(string); ok {
			return id
		}
	}
	return "system"
}

// 从上下文获取用户名的辅助函数
func getUserNameFromContext(c *gin.Context) string {
	if userName, exists := c.Get("user_name"); exists {
		if name, ok := userName.(string); ok {
			return name
		}
	}
	return "系统"
}
